package by.averianov.discounta.webapp.page.user;

import java.util.Iterator;

import javax.inject.Inject;
import javax.persistence.NoResultException;
import javax.persistence.metamodel.SingularAttribute;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Page;
import org.apache.wicket.authroles.authorization.strategies.role.annotations.AuthorizeInstantiation;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow.PageCreator;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.OrderByBorder;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.navigation.paging.PagingNavigator;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import by.averianov.discounta.datamodel.Card;
import by.averianov.discounta.datamodel.Card_;
import by.averianov.discounta.datamodel.UserAccount;
import by.averianov.discounta.datamodel.UserProfile;
import by.averianov.discounta.services.UserService;
import by.averianov.discounta.webapp.app.BasicAuthenticationSession;
import by.averianov.discounta.webapp.page.BaseLayout;
import by.averianov.discounta.webapp.page.create.CreateUser;
import by.averianov.discounta.webapp.page.table.Row;
import by.averianov.discounta.webapp.page.tabs.TabShop;
import by.averianov.discounta.webapp.page.user.addcard.AddCard;

@AuthorizeInstantiation({ "user", "administrator", "economist", "spokesman" })
public class UserProfilePage extends BaseLayout {

	private static final Logger LOGGER = LoggerFactory.getLogger(TabShop.class);
	private static final String NOT_ADD_CARD = (new ResourceModel("p.profile.cardnotadd")).toString();
	private PageCreator pageCreator;
	private UserAccount userAccount;
	private UserProfile userProfile;
	private String labelCardNumberText;
	private String labelCardStatusText;
	private String labelCardPercentText;
	private String labelCardSumText;
	
	public UserProfilePage(PageCreator pageCreator) {
		super(null);
		super.currentMenu = "profile";
		this.pageCreator = pageCreator;	
		this.labelCardNumberText = NOT_ADD_CARD;
		this.labelCardStatusText = NOT_ADD_CARD;
		this.labelCardPercentText = NOT_ADD_CARD;
		this.labelCardSumText = NOT_ADD_CARD;
	}
	
	@Inject
	private UserService userService;
	
	private class CardDataProvider extends SortableDataProvider<Card, SingularAttribute<Card, ?>> {

		public CardDataProvider() {
			super();
			setSort(Card_.id, SortOrder.ASCENDING);
		}
	
		@Override
		public Iterator<? extends Card> iterator(long first, long count) {
	
			SingularAttribute<Card, ?> sortParam = getSort().getProperty();
			SortOrder propertySortOrder = getSortState().getPropertySortOrder(sortParam);
			boolean ascending = SortOrder.ASCENDING.equals(propertySortOrder);
			return userService.getAllCardByUser(sortParam, ascending, (int) first, (int) count, userProfile.getId()).iterator();
		}
	
		@Override
		public long size() {
			return userService.getCardCount();
		}
	
		@Override
		public IModel<Card> model(Card card) {
			return new CompoundPropertyModel<Card>(card);
		}
	}

	@Override
	protected void onInitialize() {
		super.onInitialize();
		
		userProfile = BasicAuthenticationSession.get().getUserProfile();
		userAccount = userService.getUserAccount(userProfile.getId());
		
		final Label userFirstName = new Label("userFirstName",  Model.of(userProfile.getUserFirstName()));
		final Label userLastName = new Label("userLastName",  Model.of(userProfile.getUserLastName()));
		final Label labelUserIdText = new SecuredLabelForAdmin("labelUserIdText",  Model.of(userProfile.getId())) {};
		final Label labelUserId = new SecuredLabelForAdmin("labelUserId",  Model.of(getLabelUserIdText())) {};
		final Label labelUserEmailText = new Label("labelUserEmailText",  Model.of(userAccount.getUserEmail()));
		final Label labelAccessGroupText = new Label("labelAccessGroupText",  Model.of(userProfile.getAccessGroup()));
		final Label labelPhoneNumberText = new Label("labelPhoneNumberText",  Model.of(userProfile.getPhoneNumber()));
		final Label labelDateCreate = new Label("labelDateCreate",  Model.of(userProfile.getUserDateCreated()));
		
		add(userFirstName);		
		add(userLastName);
		add(labelUserIdText);
		add(labelUserId);
		add(labelUserEmailText);
		add(labelAccessGroupText);
		add(labelPhoneNumberText);
		add(labelDateCreate);
		
		Link linkAddCard = new Link("linkAddCard") {
			@Override
			public void onClick() {				
				setResponsePage(new AddCard(new PageCreator() {

					@Override
					public Page createPage() {
						return new UserProfilePage(pageCreator);
					}
				}));
				LOGGER.debug("Add Card to Profile " + userProfile.getId());
			}
		};
		add(linkAddCard);
		
		Link linkChange = new Link("linkChangeProfile") {
			@Override
			public void onClick() {				
				setResponsePage(new CreateUser(userAccount, userProfile, new PageCreator() {

					@Override
					public Page createPage() {
						return new UserProfilePage(pageCreator);
					}
				}));
				LOGGER.debug("Change Profile");
			}
		};
		add(linkChange);
		
		Link linkCancel = new Link("linkCancel"){
			@Override
			public void onClick() {
				setResponsePage(pageCreator.createPage());
				
			}
		};
		linkCancel.add(new Label("labelCancel", getButtonCancel()));
		add(linkCancel);
		
		CardDataProvider cardDataProvider = new CardDataProvider();

		final WebMarkupContainer tableProfile = new WebMarkupContainer("tableProfile");
		add(tableProfile);
		final WebMarkupContainer tableBody = new WebMarkupContainer("wrapper-body") {
			@Override
			protected void onBeforeRender() {
				super.onBeforeRender();
			}
		};
	
		tableBody.setOutputMarkupId(true);
		tableProfile.add(tableBody);
	
		DataView<Card> dataView = new DataView<Card>("list", cardDataProvider, 6) {

			@Override
			protected void populateItem(Item<Card> item) {
				final Card card = item.getModelObject();
		
				item.add(new Row("row", card, false, currentMenu));
				item.setVisible(true);                				
			}
			
		};
	
		tableBody.add(dataView);	
		tableProfile.add(new PagingNavigator("paging", dataView));	
		tableProfile.add(new OrderByBorder<SingularAttribute<Card, ?>>("sortById", Card_.id, cardDataProvider));
		tableProfile.add(new OrderByBorder<SingularAttribute<Card, ?>>("sortByType", Card_.cardType, cardDataProvider));
		tableProfile.add(new OrderByBorder<SingularAttribute<Card, ?>>("sortByStatus", Card_.cardStatus, cardDataProvider));
		tableProfile.add(new OrderByBorder<SingularAttribute<Card, ?>>("sortByDateStart", Card_.cardDateStart, cardDataProvider));
		try {
			userService.getCardByUser(userProfile.getId());
		} catch (NoResultException e) {
			tableProfile.add(AttributeModifier.append("class", "hidden"));
		}
		LOGGER.debug("onInitialize table");
		
	}

}
